Skip to content

Commit 4af7c00

Browse files
committed
pyevmasm, tests: Add support for multiple forks.
* separate instruction tables for pre-byzantium, byzantium and constantinopole. * added new optional argument to CLI (--fork, -f) that accepts fork to be used. * it is possible to select fork by name or by block number. * introduced default fork selection by introducing DEFAULT_FORK constant * added 3 new test cases, one per supported fork * fixed test_ADD_1 test case All functions and evmasm are fully backwards compatible. If no fork is selected, "byzantium" is chosen by default. Example usage: ``` evmasm -t -f 0 evmasm -t -f 3700000 evmasm -t -f 4369999 evmasm -t -f pre-byzantium evmasm -t evmasm -t -f 4370000 evmasm -t -f 4370001 evmasm -t -f byzantium evmasm -t -f 9999999 (block number to be updated after mainnet launch) evmasm -t -f constantinople ``` Error handling: ``` $ evmasm -t -f a Wrong fork name or block number. Please provide an integer or one of ['pre-byzantium', 'byzantium', 'constantinople']. $ evmasm -t -f constantinoplee Wrong fork name or block number. Please provide an integer or one of ['pre-byzantium', 'byzantium', 'constantinople']. $ evmasm -t -f 1.2 Wrong fork name or block number. Please provide an integer or one of ['pre-byzantium', 'byzantium', 'constantinople']. $ evmasm -t -f usage: evmasm [-h] (-a | -d | -t) [-bi] [-bo] [-i [INPUT]] [-o [OUTPUT]] [-f FORK] evmasm: error: argument -f/--fork: expected 1 argument ``` Refs: #7
1 parent 0a9287c commit 4af7c00

File tree

5 files changed

+422
-28
lines changed

5 files changed

+422
-28
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ optional arguments:
2323
Input file, default=stdin
2424
-o [OUTPUT], --output [OUTPUT]
2525
Output file, default=stdout
26+
-f FORK, --fork FORK Fork, default: byzantium. Possible: [pre-byzantium,
27+
byzantium, constantinople]. Also an unsigned block
28+
number is accepted to select the fork.
2629
```
2730

2831
Disassembling the preamble of compiled contract:
@@ -44,7 +47,8 @@ $ echo -n "608060405260043610603f57600035" | evmasm -d
4447
## Python API Examples
4548

4649
```
47-
>>> from pyevmasm import instruction_table, disassemble_hex, disassemble_all, assemble_hex
50+
>>> from pyevmasm import instruction_tables, disassemble_hex, disassemble_all, assemble_hex
51+
>>> instruction_table = instruction_tables['byzantium']
4852
>>> instruction_table[20]
4953
Instruction(0x14, 'EQ', 0, 2, 1, 3, 'Equality comparision.', None, 0)
5054
>>> instruction_table['EQ']

pyevmasm/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
from .evmasm import instruction_table, Instruction # noqa: F401
1+
from .evmasm import instruction_tables, Instruction # noqa: F401
2+
from .evmasm import block_to_fork, DEFAULT_FORK
23
from .evmasm import assemble, assemble_all, assemble_hex, assemble_one
34
from .evmasm import disassemble, disassemble_all, disassemble_hex, disassemble_one

pyevmasm/__main__.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import sys
44
import binascii
55

6-
from .evmasm import assemble_hex, disassemble_all, instruction_table, assemble_all
6+
from .evmasm import assemble_hex, disassemble_all, instruction_tables, assemble_all, block_to_fork, DEFAULT_FORK
77

88

99
def main():
@@ -18,9 +18,26 @@ def main():
1818
help='Input file, default=stdin')
1919
parser.add_argument('-o', '--output', nargs='?', default=sys.stdout, type=argparse.FileType('w'),
2020
help='Output file, default=stdout')
21+
parser.add_argument('-f', '--fork', default=DEFAULT_FORK, type=str,
22+
help='Fork, default: byzantium. Possible: [pre-byzantium, byzantium, constantinople].'
23+
'Also an unsigned block number is accepted to select the fork.')
2124

2225
args = parser.parse_args(sys.argv[1:])
2326

27+
accepted_forks = ['pre-byzantium', 'byzantium', 'constantinople']
28+
arg_fork = args.fork.lower()
29+
if arg_fork not in accepted_forks:
30+
try:
31+
block_number = abs(int(arg_fork))
32+
fork = block_to_fork(block_number)
33+
except ValueError:
34+
sys.stderr.write('Wrong fork name or block number. '
35+
'Please provide an integer or one of %s.\n' % accepted_forks)
36+
sys.exit(1)
37+
else:
38+
fork = arg_fork
39+
40+
instruction_table = instruction_tables[fork]
2441
if args.print_opcode_table:
2542
for instr in instruction_table:
2643
print('0x{:02x}: {:16s} {:s}'.format(instr.opcode, instr.name, instr.description))
@@ -32,13 +49,13 @@ def main():
3249
except KeyboardInterrupt:
3350
sys.exit(0)
3451
if args.binary_output:
35-
for i in assemble_all(asm):
52+
for i in assemble_all(asm, fork=fork):
3653
if sys.version_info >= (3, 2):
3754
args.output.buffer.write(i.bytes)
3855
else:
3956
args.output.write(i.bytes)
4057
else:
41-
args.output.write(assemble_hex(asm) + "\n")
58+
args.output.write(assemble_hex(asm, fork=fork) + "\n")
4259

4360
if args.disassemble:
4461
if args.binary_input and sys.version_info >= (3, 2):
@@ -65,7 +82,7 @@ def main():
6582
if buf_set <= hex_set: # subset
6683
buf = binascii.unhexlify(buf)
6784

68-
insns = list(disassemble_all(buf))
85+
insns = list(disassemble_all(buf, fork=fork))
6986
for i in insns:
7087
args.output.write("%08x: %s\n" % (i.pc, str(i)))
7188

0 commit comments

Comments
 (0)