evm_rs/
decode.rs

1// This is free and unencumbered software released into the public domain.
2
3use ethnum::u256;
4
5use crate::{error::DecodeError, opcode::Opcode, program::Program};
6
7pub fn decode_program(input: &[u8]) -> Result<Program, DecodeError> {
8    Ok(Program(decode_opcodes(input)?))
9}
10
11pub fn decode_opcodes(input: &[u8]) -> Result<Vec<Opcode>, DecodeError> {
12    let mut result = Vec::new();
13    let mut input_pos: usize = 0;
14    while input_pos < input.len() {
15        match decode_opcode(&input[input_pos..]) {
16            Err(err) => return Err(err),
17            Ok(op) => {
18                input_pos += op.size();
19                result.push(op);
20            }
21        }
22    }
23    Ok(result)
24}
25
26pub fn decode_opcode(input: &[u8]) -> Result<Opcode, DecodeError> {
27    use Opcode::*;
28    let opcode = input[0];
29    let invalid = Err(DecodeError::InvalidOpcode(opcode));
30    let result = match opcode {
31        0x00 => STOP,
32        0x01 => ADD,
33        0x02 => MUL,
34        0x03 => SUB,
35        0x04 => DIV,
36        0x05 => SDIV,
37        0x06 => MOD,
38        0x07 => SMOD,
39        0x08 => ADDMOD,
40        0x09 => MULMOD,
41        0x0A => EXP,
42        0x0B => SIGNEXTEND,
43        0x0C..=0x0F => return invalid,
44        0x10 => LT,
45        0x11 => GT,
46        0x12 => SLT,
47        0x13 => SGT,
48        0x14 => EQ,
49        0x15 => ISZERO,
50        0x16 => AND,
51        0x17 => OR,
52        0x18 => XOR,
53        0x19 => NOT,
54        0x1A => BYTE,
55        0x1B => SHL,
56        0x1C => SHR,
57        0x1D => SAR,
58        0x1E..=0x1F => return invalid,
59        0x20 => SHA3,
60        0x21..=0x2F => return invalid,
61        0x30 => ADDRESS,
62        0x31 => BALANCE,
63        0x32 => ORIGIN,
64        0x33 => CALLER,
65        0x34 => CALLVALUE,
66        0x35 => CALLDATALOAD,
67        0x36 => CALLDATASIZE,
68        0x37 => CALLDATACOPY,
69        0x38 => CODESIZE,
70        0x39 => CODECOPY,
71        0x3A => GASPRICE,
72        0x3B => EXTCODESIZE,
73        0x3C => EXTCODECOPY,
74        0x3D => RETURNDATASIZE,
75        0x3E => RETURNDATACOPY,
76        0x3F => EXTCODEHASH,
77        0x40 => BLOCKHASH,
78        0x41 => COINBASE,
79        0x42 => TIMESTAMP,
80        0x43 => NUMBER,
81        0x44 => DIFFICULTY,
82        0x45 => GASLIMIT,
83        0x46 => CHAINID,
84        0x47 => SELFBALANCE,
85        0x48 => BASEFEE,
86        0x49..=0x4F => return invalid,
87        0x50 => POP,
88        0x51 => MLOAD,
89        0x52 => MSTORE,
90        0x53 => MSTORE8,
91        0x54 => SLOAD,
92        0x55 => SSTORE,
93        0x56 => JUMP,
94        0x57 => JUMPI,
95        0x58 => PC,
96        0x59 => MSIZE,
97        0x5A => GAS,
98        0x5B => JUMPDEST,
99        0x5C..=0x5F => return invalid,
100        0x60 => PUSH1(input[1]),
101        0x61..=0x7F => {
102            let n = opcode - 0x60 + 1;
103            let mut buffer: [u8; 32] = [0; 32];
104            buffer[(32 - (n as usize))..32].copy_from_slice(&input[1..=n.into()]);
105            PUSHn(
106                n,
107                u256::from_be_bytes(buffer),
108                buffer[(32 - (n as usize))..32].to_vec(),
109            )
110        }
111        0x80..=0x8F => DUP(opcode - 0x80 + 1),
112        0x90..=0x9F => SWAP(opcode - 0x90 + 1),
113        0xA0..=0xA4 => LOG(opcode - 0xA0),
114        0xA5..=0xEF => return invalid,
115        0xF0 => CREATE,
116        0xF1 => CALL,
117        0xF2 => CALLCODE,
118        0xF3 => RETURN,
119        0xF4 => DELEGATECALL,
120        0xF5 => CREATE2,
121        0xF6..=0xF9 => return invalid,
122        0xFA => STATICCALL,
123        0xFB..=0xFC => return invalid,
124        0xFD => REVERT,
125        0xFE => INVALID,
126        0xFF => SELFDESTRUCT,
127        //opcode => return invalid,
128    };
129    Ok(result)
130}