You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

236 lines
8.1 KiB

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