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.

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