1use 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 };
129 Ok(result)
130}