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.

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