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