evm-rs/src/lib.rs
src/lib.rsRaw
1#![allow(dead_code)]
2
3use std::collections::HashMap;
4pub mod opcodes;
5pub mod u256;
6
7#[derive(Default)]
8pub struct Stack {
9 pub pc: usize,
10 pub calldata_i: usize,
11 pub calldata_size: usize,
12 pub stack: Vec<[u8; 32]>,
13 pub storage_committed: HashMap<[u8; 32], Vec<u8>>,
14 pub storage: HashMap<[u8; 32], Vec<u8>>,
15 pub mem: Vec<u8>,
16 pub gas: u64,
17 pub opcodes: HashMap<u8, opcodes::Opcode>,
18}
19
20impl Stack {
21 pub fn new() -> Stack {
22 let mut s = Stack {
23 pc: 0,
24 calldata_i: 0,
25 calldata_size: 32,
26 stack: Vec::new(),
27 storage_committed: HashMap::new(),
28 storage: HashMap::new(),
29 mem: Vec::new(),
30 gas: 10000000000,
31 opcodes: HashMap::new(),
32 };
33 s.opcodes = opcodes::new_opcodes();
34 s
35 }
36 pub fn print_stack(&self) {
37 println!("stack ({}):", self.stack.len());
38 for i in (0..self.stack.len()).rev() {
39 // println!("{:x}", &self.stack[i][28..]);
40 println!("{:?}", vec_u8_to_hex(self.stack[i].to_vec()));
41 }
42 }
43 pub fn print_memory(&self) {
44 if !self.mem.is_empty() {
45 println!("memory ({}):", self.mem.len());
46 println!("{:?}", vec_u8_to_hex(self.mem.to_vec()));
47 }
48 }
49 pub fn print_storage(&self) {
50 if !self.storage.is_empty() {
51 println!("storage ({}):", self.storage.len());
52 for (key, value) in self.storage.iter() {
53 println!(
54 "{:?}: {:?}",
55 vec_u8_to_hex(key.to_vec()),
56 vec_u8_to_hex(value.to_vec())
57 );
58 }
59 }
60 }
61 pub fn push(&mut self, b: [u8; 32]) {
62 self.stack.push(b);
63 }
64 // push_arbitrary performs a push, but first converting the arbitrary-length
65 // input into a 32 byte array
66 pub fn push_arbitrary(&mut self, b: &[u8]) {
67 // TODO if b.len()>32 return error
68 let mut d: [u8; 32] = [0; 32];
69 d[32 - b.len()..].copy_from_slice(b);
70 self.stack.push(d);
71 }
72 // put_arbitrary puts in the last element of the stack the value
73 pub fn put_arbitrary(&mut self, b: &[u8]) {
74 // TODO if b.len()>32 return error
75 let mut d: [u8; 32] = [0; 32];
76 d[0..b.len()].copy_from_slice(b); // put without left padding
77 let l = self.stack.len();
78 self.stack[l - 1] = d;
79 }
80 pub fn pop(&mut self) -> Result<[u8; 32], String> {
81 match self.stack.pop() {
82 Some(x) => Ok(x),
83 None => Err("pop err".to_string()), // WIP
84 }
85 }
86 pub fn peek(&mut self) -> Result<[u8; 32], String> {
87 if self.stack.is_empty() {
88 return Err("peek err".to_string());
89 }
90 Ok(self.stack[self.stack.len() - 1])
91 }
92 pub fn substract_gas(&mut self, val: u64) -> Result<(), String> {
93 if self.gas < val {
94 return Err("out of gas".to_string());
95 }
96 self.gas -= val;
97 Ok(())
98 }
99
100 pub fn execute(
101 &mut self,
102 code: &[u8],
103 calldata: &[u8],
104 debug: bool,
105 ) -> Result<Vec<u8>, String> {
106 self.pc = 0;
107 self.calldata_i = 0;
108 let l = code.len();
109
110 while self.pc < l {
111 let opcode = code[self.pc];
112 if !self.opcodes.contains_key(&opcode) {
113 return Err(format!("invalid opcode {:x}", opcode));
114 }
115
116 if debug {
117 println!(
118 "{} (0x{:x}): pc={:?} gas={:?}",
119 self.opcodes.get(&opcode).unwrap().name,
120 opcode,
121 self.pc,
122 self.gas,
123 );
124 self.print_stack();
125 self.print_memory();
126 self.print_storage();
127 println!();
128 }
129 match opcode & 0xf0 {
130 0x00 => {
131 // arithmetic
132 match opcode {
133 0x00 => {
134 println!("0x00: STOP");
135 return Ok(Vec::new());
136 }
137 0x01 => self.add()?,
138 0x02 => self.mul()?,
139 0x03 => self.sub()?,
140 0x04 => self.div()?,
141 0x05 => self.sdiv()?,
142 0x06 => self.modulus()?,
143 0x07 => self.smod()?,
144 0x08 => self.add_mod()?,
145 0x09 => self.mul_mod()?,
146 0x0a => self.exp()?,
147 // 0x0b => self.sign_extend(),
148 _ => return Err(format!("unimplemented {:x}", opcode)),
149 }
150 self.pc += 1;
151 }
152 0x10 => {
153 // arithmetic
154 match opcode {
155 0x10 => self.lt()?,
156 0x11 => self.gt()?,
157 // 0x12 => self.slt()?,
158 // 0x13 => self.sgt()?,
159 0x14 => self.eq()?,
160 0x15 => self.is_zero()?,
161 0x16 => self.and()?,
162 0x17 => self.or()?,
163 0x18 => self.xor()?,
164 0x19 => self.not()?,
165 // 0x1a => self.byte()?,
166 _ => return Err(format!("unimplemented {:x}", opcode)),
167 }
168 self.pc += 1;
169 }
170 0x30 => {
171 match opcode {
172 0x35 => self.calldata_load(&calldata)?,
173 0x36 => self.calldata_size(&calldata),
174 0x39 => self.code_copy(&code)?,
175 _ => return Err(format!("unimplemented {:x}", opcode)),
176 }
177 self.pc += 1;
178 }
179 0x50 => {
180 self.pc += 1;
181 match opcode {
182 0x51 => self.mload()?,
183 0x52 => self.mstore()?,
184 0x55 => self.sstore()?,
185 0x56 => self.jump(code)?,
186 0x57 => self.jump_i(code)?,
187 0x5b => self.jump_dest()?,
188 _ => return Err(format!("unimplemented {:x}", opcode)),
189 }
190 }
191 0x60 | 0x70 => {
192 // push
193 let n = (opcode - 0x5f) as usize;
194 self.push_arbitrary(&code[self.pc + 1..self.pc + 1 + n]);
195 self.pc += 1 + n;
196 }
197 0x80 => {
198 // 0x8x dup
199 let l = self.stack.len();
200 if opcode > 0x7f {
201 self.stack.push(self.stack[l - (opcode - 0x7f) as usize]);
202 } else {
203 self.stack.push(self.stack[(0x7f - opcode) as usize]);
204 }
205 self.pc += 1;
206 }
207 0x90 => {
208 // 0x9x swap
209 let l = self.stack.len();
210 let pos;
211 if opcode > 0x8e {
212 pos = l - (opcode - 0x8e) as usize;
213 } else {
214 pos = (0x8e - opcode) as usize;
215 }
216 self.stack.swap(pos, l - 1);
217 self.pc += 1;
218 }
219 0xf0 => {
220 if opcode == 0xf3 {
221 let pos_to_return = u256::u256_to_u64(self.pop()?) as usize;
222 let len_to_return = u256::u256_to_u64(self.pop()?) as usize;
223 return Ok(self.mem[pos_to_return..pos_to_return + len_to_return].to_vec());
224 }
225 }
226 _ => {
227 return Err(format!("unimplemented {:x}", opcode));
228 }
229 }
230 self.substract_gas(self.opcodes.get(&opcode).unwrap().gas)?;
231 }
232 Ok(Vec::new())
233 }
234}
235pub fn vec_u8_to_hex(bytes: Vec<u8>) -> String {
236 let strs: Vec<String> = bytes.iter().map(|b| format!("{:02X}", b)).collect();
237 strs.join("")
238}