diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d9bacfd..ba9e8d8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,10 +11,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up Python 3.7 + - name: Set up Python 3.8 uses: actions/setup-python@v4 with: - python-version: 3.7 + python-version: 3.8 - name: Lint if: github.event_name == 'pull_request' env: @@ -23,23 +23,23 @@ jobs: run: | pip install black pip install mypy - python setup.py install + pip install -e . black --version black pyevmasm mypy --version mypy pyevmasm - test37: + test38: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up Python 3.7 + - name: Set up Python 3.8 uses: actions/setup-python@v4 with: - python-version: 3.7 - - name: Run Tests 37 + python-version: 3.8 + - name: Run Tests 38 run: | - python setup.py install + pip install -e . python -m unittest discover "tests/" diff --git a/pyevmasm/evmasm.py b/pyevmasm/evmasm.py index 816ed6d..7cf73fe 100644 --- a/pyevmasm/evmasm.py +++ b/pyevmasm/evmasm.py @@ -1107,7 +1107,9 @@ def __repr__(self): london_instruction_table, previous_fork=istanbul_instruction_table ) -shanghai_instruction_table = {0x5f: ("PUSH", 0, 0, 1, 2, "Place 0 constant byte item on stack.")} +shanghai_instruction_table = { + 0x5F: ("PUSH", 0, 0, 1, 2, "Place 0 constant byte item on stack.") +} shanghai_instruction_table = InstructionTable( # type: ignore shanghai_instruction_table, previous_fork=london_instruction_table diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..08584ee --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,59 @@ +[build-system] +requires = ["setuptools>=45", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "pyevmasm" +version = "0.2.4" +description = "Ethereum Virtual Machine (EVM) assembler and disassembler" +authors = [ + {name = "Trail of Bits", email = "evmasm@trailofbits.com"} +] +license = {text = "Apache License 2.0"} +readme = "README.md" +requires-python = ">=3.8" +dependencies = [ + "future" +] +keywords = ["ethereum", "evm", "assembler", "disassembler", "blockchain"] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: Security", + "Topic :: Software Development :: Disassemblers", +] + +[project.urls] +Homepage = "https://github.com/trailofbits/pyevmasm" +Repository = "https://github.com/trailofbits/pyevmasm" +Issues = "https://github.com/trailofbits/pyevmasm/issues" + +[project.scripts] +evmasm = "pyevmasm.__main__:main" + +[project.optional-dependencies] +dev = ["nose", "coverage", "flake8", "flake8-pyproject"] +test = ["nose", "coverage"] + +[tool.setuptools] +packages = ["pyevmasm"] + +[tool.black] +line-length = 160 +target-version = ['py38'] + +[tool.flake8] +max-line-length = 160 +exclude = [".tox", ".*.egg", ".git", "docs/", "examples/", "scripts/", "tests/", ".venv/"] + +[tool.coverage.run] +source = ["pyevmasm"] +omit = ["tests/*"] + diff --git a/setup.py b/setup.py deleted file mode 100644 index 5624c27..0000000 --- a/setup.py +++ /dev/null @@ -1,28 +0,0 @@ -from setuptools import setup - -setup( - name='pyevmasm', - version='0.2.4', - description='Ethereum Virtual Machine (EVM) assembler and disassembler', - author='Trail of Bits', - author_email='evmasm@trailofbits.com', - url='https://github.com/trailofbits/pyevmasm', - license='Apache License 2.0', - packages=['pyevmasm'], - python_requires='>2.7', - install_requires=[ - 'future' - ], - extras_require={ - 'dev': [ - 'nose', - 'coverage', - 'flake8' - ] - }, - entry_points={ - 'console_scripts': [ - 'evmasm = pyevmasm.__main__:main' - ] - } -) diff --git a/tests/test_EVMAssembler.py b/tests/test_EVMAssembler.py index 43ab08a..003ecc6 100644 --- a/tests/test_EVMAssembler.py +++ b/tests/test_EVMAssembler.py @@ -19,12 +19,18 @@ class EVMTest_Assembler(unittest.TestCase): def test_ADD_1(self): instruction = EVMAsm.disassemble_one(b"\x60\x10") self.assertEqual( - EVMAsm.Instruction(0x60, "PUSH", 1, 0, 1, 3, "Place 1 byte item on stack.", 16, 0), instruction + EVMAsm.Instruction( + 0x60, "PUSH", 1, 0, 1, 3, "Place 1 byte item on stack.", 16, 0 + ), + instruction, ) instruction = EVMAsm.assemble_one("PUSH1 0x10") self.assertEqual( - instruction, EVMAsm.Instruction(0x60, "PUSH", 1, 0, 1, 3, "Place 1 byte item on stack.", 16, 0) + instruction, + EVMAsm.Instruction( + 0x60, "PUSH", 1, 0, 1, 3, "Place 1 byte item on stack.", 16, 0 + ), ) instructions1 = EVMAsm.disassemble_all(b"\x30\x31") @@ -44,7 +50,9 @@ def test_ADD_1(self): self.assertEqual(bytecode, "0x608040526002610100") asmcode = EVMAsm.disassemble_hex("0x608040526002610100") - self.assertEqual(asmcode, """PUSH1 0x80\nBLOCKHASH\nMSTORE\nPUSH1 0x2\nPUSH2 0x100""") + self.assertEqual( + asmcode, """PUSH1 0x80\nBLOCKHASH\nMSTORE\nPUSH1 0x2\nPUSH2 0x100""" + ) def test_STOP(self): insn = EVMAsm.disassemble_one(b"\x00") @@ -75,7 +83,9 @@ def test_byzantium_fork(self): insn = EVMAsm.disassemble_one(b"\x1d", fork="byzantium") self.assertTrue(insn.mnemonic == "INVALID") # SAR added in constantinople insn = EVMAsm.disassemble_one(b"\x3f", fork="byzantium") - self.assertTrue(insn.mnemonic == "INVALID") # EXTCODEHASH added in constantinople + self.assertTrue( + insn.mnemonic == "INVALID" + ) # EXTCODEHASH added in constantinople insn = EVMAsm.disassemble_one(b"\xf5", fork="byzantium") self.assertTrue(insn.mnemonic == "INVALID") # CREATE2 added in constantinople @@ -120,7 +130,7 @@ def test_istanbul_fork(self): self.assertTrue(insn.fee == 800) self.assertTrue(insn.pops == 1) self.assertTrue(insn.pushes == 1) - + def test_london_fork(self): insn = EVMAsm.disassemble_one(b"\x48", fork="london") self.assertTrue(insn.mnemonic == "BASEFEE") @@ -173,9 +183,13 @@ def test_assemble_LOGX_regression(self): log0_opcode = 0xA0 for n in range(5): opcode = log0_opcode + n - self.assertTrue(opcode in inst_table, "{!r} not in instruction_table".format(opcode)) + self.assertTrue( + opcode in inst_table, "{!r} not in instruction_table".format(opcode) + ) asm = "LOG" + str(n) - self.assertTrue(asm in inst_table, "{!r} not in instruction_table".format(asm)) + self.assertTrue( + asm in inst_table, "{!r} not in instruction_table".format(asm) + ) insn = EVMAsm.assemble_one(asm) self.assertEqual(insn.mnemonic, asm) self.assertEqual(insn.opcode, opcode) diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 68532a2..0000000 --- a/tox.ini +++ /dev/null @@ -1,23 +0,0 @@ -[tox] -envlist = py{27,36} - -[testenv] -deps = .[dev] -commands = nosetests -install_command = pip install {opts} {packages} - -[testenv:pep8] -basepython = python2.7 -deps = flake8 -commands = - flake8 . - -[pep8] -ignore = E265,E501 -max-line-length = 160 -exclude = docs/,examples/,scripts/,tests/ - -[flake8] -#ignore = E265,E501,F403,F405,E266,E712,F841,E741,E722,E731 -max-line-length = 160 -exclude = .tox,.*.egg,.git,docs/,examples/,scripts/,tests/