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.

418 lines
14 KiB

  1. #![allow(dead_code)]
  2. use num_bigint::BigUint;
  3. use std::collections::HashMap;
  4. // Non-opcode gas prices
  5. const GDEFAULT: usize = 1;
  6. const GMEMORY: usize = 3;
  7. const GQUADRATICMEMDENOM: usize = 512; // 1 gas per 512 quadwords
  8. const GSTORAGEREFUND: usize = 15000;
  9. const GSTORAGEKILL: usize = 5000;
  10. const GSTORAGEMOD: usize = 5000;
  11. const GSTORAGEADD: usize = 20000;
  12. const GEXPONENTBYTE: usize = 10; // cost of EXP exponent per byte
  13. const GCOPY: usize = 3; // cost to copy one 32 byte word
  14. const GCONTRACTBYTE: usize = 200; // one byte of code in contract creation
  15. const GCALLVALUETRANSFER: usize = 9000; // non-zero-valued call
  16. const GLOGBYTE: usize = 8; // cost of a byte of logdata
  17. const GTXCOST: usize = 21000; // TX BASE GAS COST
  18. const GTXDATAZERO: usize = 4; // TX DATA ZERO BYTE GAS COST
  19. const GTXDATANONZERO: usize = 68; // TX DATA NON ZERO BYTE GAS COST
  20. const GSHA3WORD: usize = 6; // Cost of SHA3 per word
  21. const GSHA256BASE: usize = 60; // Base c of SHA256
  22. const GSHA256WORD: usize = 12; // Cost of SHA256 per word
  23. const GRIPEMD160BASE: usize = 600; // Base cost of RIPEMD160
  24. const GRIPEMD160WORD: usize = 120; // Cost of RIPEMD160 per word
  25. const GIDENTITYBASE: usize = 15; // Base cost of indentity
  26. const GIDENTITYWORD: usize = 3; // Cost of identity per word
  27. const GECRECOVER: usize = 3000; // Cost of ecrecover op
  28. const GSTIPEND: usize = 2300;
  29. const GCALLNEWACCOUNT: usize = 25000;
  30. const GSUICIDEREFUND: usize = 24000;
  31. pub struct Stack {
  32. pc: usize,
  33. calldata_i: usize,
  34. stack: Vec<[u8; 32]>,
  35. mem: Vec<u8>,
  36. gas: u64,
  37. opcodes: HashMap<u8, Opcode>,
  38. }
  39. impl Stack {
  40. pub fn new() -> Stack {
  41. let mut s = Stack {
  42. pc: 0,
  43. calldata_i: 0,
  44. stack: Vec::new(),
  45. mem: Vec::new(),
  46. gas: 10000000000,
  47. opcodes: HashMap::new(),
  48. };
  49. s.opcodes = new_opcodes();
  50. s
  51. }
  52. fn push(&mut self, b: [u8; 32]) {
  53. self.stack.push(b);
  54. }
  55. // push_arbitrary performs a push, but first converting the arbitrary-length input into a 32
  56. // byte array
  57. fn push_arbitrary(&mut self, b: &[u8]) {
  58. // TODO if b.len()>32 return error
  59. let mut d: [u8; 32] = [0; 32];
  60. d[32 - b.len()..].copy_from_slice(&b[..]);
  61. self.stack.push(d);
  62. }
  63. fn pop(&mut self) -> [u8; 32] {
  64. match self.stack.pop() {
  65. Some(x) => return x,
  66. None => panic!("err"),
  67. }
  68. }
  69. fn execute(&mut self, code: &[u8], calldata: &[u8], debug: bool) -> Vec<u8> {
  70. self.pc = 0;
  71. self.calldata_i = 0;
  72. let l = code.len();
  73. while self.pc < l {
  74. let opcode = code[self.pc];
  75. if !self.opcodes.contains_key(&opcode) {
  76. panic!("invalid opcode {:x}", opcode);
  77. }
  78. match opcode & 0xf0 {
  79. 0x00 => {
  80. // arithmetic
  81. match opcode {
  82. 0x00 => {
  83. return Vec::new();
  84. }
  85. 0x01 => self.add(),
  86. 0x02 => self.mul(),
  87. 0x03 => self.sub(),
  88. 0x04 => self.div(),
  89. 0x05 => self.sdiv(),
  90. 0x06 => self.modulus(),
  91. 0x07 => self.smod(),
  92. 0x08 => self.add_mod(),
  93. 0x09 => self.mul_mod(),
  94. 0x0a => self.exp(),
  95. // 0x0b => self.sign_extend(),
  96. _ => panic!("unimplemented {:x}", opcode),
  97. }
  98. self.pc += 1;
  99. }
  100. 0x50 => {
  101. self.pc += 1;
  102. match opcode {
  103. 0x52 => self.mstore(),
  104. _ => panic!("unimplemented {:x}", opcode),
  105. }
  106. }
  107. 0x60 | 0x70 => {
  108. // push
  109. let n = (opcode - 0x5f) as usize;
  110. self.push_arbitrary(&code[self.pc + 1..self.pc + 1 + n]);
  111. self.pc += 1 + n;
  112. }
  113. 0xf0 => {
  114. if opcode == 0xf3 {
  115. let pos_to_return = u256_to_u64(self.pop()) as usize;
  116. let len_to_return = u256_to_u64(self.pop()) as usize;
  117. return self.mem[pos_to_return..pos_to_return + len_to_return].to_vec();
  118. }
  119. }
  120. _ => {
  121. panic!("unimplemented {:x}", opcode);
  122. }
  123. }
  124. self.gas -= self.opcodes.get(&opcode).unwrap().gas;
  125. }
  126. return Vec::new();
  127. }
  128. // arithmetic
  129. // TODO instead of [u8;32] converted to BigUint, use custom type uint256 that implements all
  130. // the arithmetic
  131. fn add(&mut self) {
  132. let b0 = BigUint::from_bytes_be(&self.pop()[..]);
  133. let b1 = BigUint::from_bytes_be(&self.pop()[..]);
  134. self.push_arbitrary(&(b0 + b1).to_bytes_be());
  135. }
  136. fn mul(&mut self) {
  137. let b0 = BigUint::from_bytes_be(&self.pop()[..]);
  138. let b1 = BigUint::from_bytes_be(&self.pop()[..]);
  139. self.push_arbitrary(&(b0 * b1).to_bytes_be());
  140. }
  141. fn sub(&mut self) {
  142. let b0 = BigUint::from_bytes_be(&self.pop()[..]);
  143. let b1 = BigUint::from_bytes_be(&self.pop()[..]);
  144. if b0 >= b1 {
  145. self.push_arbitrary(&(b0 - b1).to_bytes_be());
  146. } else {
  147. // 2**256
  148. let max =
  149. "115792089237316195423570985008687907853269984665640564039457584007913129639936"
  150. .parse::<BigUint>()
  151. .unwrap();
  152. self.push_arbitrary(&(max + b0 - b1).to_bytes_be());
  153. }
  154. }
  155. fn div(&mut self) {
  156. let b0 = BigUint::from_bytes_be(&self.pop()[..]);
  157. let b1 = BigUint::from_bytes_be(&self.pop()[..]);
  158. self.push_arbitrary(&(b0 / b1).to_bytes_be());
  159. }
  160. fn sdiv(&mut self) {
  161. panic!("unimplemented");
  162. }
  163. fn modulus(&mut self) {
  164. let b0 = BigUint::from_bytes_be(&self.pop()[..]);
  165. let b1 = BigUint::from_bytes_be(&self.pop()[..]);
  166. self.push_arbitrary(&(b0 % b1).to_bytes_be());
  167. }
  168. fn smod(&mut self) {
  169. panic!("unimplemented");
  170. }
  171. fn add_mod(&mut self) {
  172. let b0 = BigUint::from_bytes_be(&self.pop()[..]);
  173. let b1 = BigUint::from_bytes_be(&self.pop()[..]);
  174. let b2 = BigUint::from_bytes_be(&self.pop()[..]);
  175. self.push_arbitrary(&(b0 + b1 % b2).to_bytes_be());
  176. }
  177. fn mul_mod(&mut self) {
  178. let b0 = BigUint::from_bytes_be(&self.pop()[..]);
  179. let b1 = BigUint::from_bytes_be(&self.pop()[..]);
  180. let b2 = BigUint::from_bytes_be(&self.pop()[..]);
  181. self.push_arbitrary(&(b0 * b1 % b2).to_bytes_be());
  182. }
  183. fn exp(&mut self) {
  184. panic!("unimplemented");
  185. // let b0 = BigUint::from_bytes_be(&self.pop()[..]);
  186. // let b1 = BigUint::from_bytes_be(&self.pop()[..]);
  187. // self.push_arbitrary(&(pow(b0, b1)).to_bytes_be());
  188. }
  189. // boolean
  190. // crypto
  191. // contract context
  192. fn calldata_load(&mut self, calldata: &[u8]) {}
  193. // blockchain context
  194. // storage and execution
  195. fn extend_mem(&mut self, start: usize, size: usize) {
  196. if size <= self.mem.len() || start + size <= self.mem.len() {
  197. return;
  198. }
  199. let old_size = self.mem.len() / 32;
  200. let new_size = (start + size) / 32;
  201. let old_total_fee = old_size * GMEMORY + old_size.pow(2) / GQUADRATICMEMDENOM;
  202. let new_total_fee = new_size * GMEMORY + new_size.pow(2) / GQUADRATICMEMDENOM;
  203. let mem_fee = new_total_fee - old_total_fee;
  204. self.gas -= mem_fee as u64;
  205. let mut new_bytes: Vec<u8> = vec![0; size];
  206. self.mem.append(&mut new_bytes);
  207. }
  208. fn mstore(&mut self) {
  209. let pos = u256_to_u64(self.pop());
  210. let val = self.pop();
  211. self.extend_mem(pos as usize, 32);
  212. self.mem[pos as usize..].copy_from_slice(&val);
  213. }
  214. }
  215. fn u256_to_u64(a: [u8; 32]) -> u64 {
  216. let mut b8: [u8; 8] = [0; 8];
  217. b8.copy_from_slice(&a[32 - 8..32]);
  218. let pos = u64::from_be_bytes(b8);
  219. pos
  220. }
  221. fn str_to_u256(s: &str) -> [u8; 32] {
  222. let bi = s.parse::<BigUint>().unwrap().to_bytes_be();
  223. let mut r: [u8; 32] = [0; 32];
  224. r[32 - bi.len()..].copy_from_slice(&bi[..]);
  225. r
  226. }
  227. struct Opcode {
  228. name: String,
  229. ins: u32,
  230. outs: u32,
  231. gas: u64,
  232. }
  233. fn new_opcode(name: &str, ins: u32, outs: u32, gas: u64) -> Opcode {
  234. Opcode {
  235. name: name.to_string(),
  236. ins,
  237. outs,
  238. gas,
  239. }
  240. }
  241. fn new_opcodes() -> HashMap<u8, Opcode> {
  242. let mut opcodes: HashMap<u8, Opcode> = HashMap::new();
  243. // arithmetic
  244. opcodes.insert(0x00, new_opcode("STOP", 0, 0, 0));
  245. opcodes.insert(0x01, new_opcode("ADD", 2, 1, 3));
  246. opcodes.insert(0x02, new_opcode("MUL", 2, 1, 5));
  247. opcodes.insert(0x03, new_opcode("SUB", 2, 1, 3));
  248. opcodes.insert(0x04, new_opcode("DIV", 2, 1, 5));
  249. opcodes.insert(0x05, new_opcode("SDIV", 2, 1, 5));
  250. opcodes.insert(0x06, new_opcode("MOD", 2, 1, 5));
  251. opcodes.insert(0x07, new_opcode("SMOD", 2, 1, 5));
  252. opcodes.insert(0x08, new_opcode("ADDMOD", 3, 1, 8));
  253. opcodes.insert(0x09, new_opcode("MULMOD", 3, 1, 8));
  254. opcodes.insert(0x0a, new_opcode("EXP", 2, 1, 10));
  255. opcodes.insert(0x0b, new_opcode("SIGNEXTEND", 2, 1, 5));
  256. // boolean
  257. opcodes.insert(0x10, new_opcode("LT", 2, 1, 3));
  258. opcodes.insert(0x11, new_opcode("GT", 2, 1, 3));
  259. opcodes.insert(0x12, new_opcode("SLT", 2, 1, 3));
  260. opcodes.insert(0x13, new_opcode("SGT", 2, 1, 3));
  261. opcodes.insert(0x14, new_opcode("EQ", 2, 1, 3));
  262. opcodes.insert(0x15, new_opcode("ISZERO", 1, 1, 3));
  263. opcodes.insert(0x16, new_opcode("AND", 2, 1, 3));
  264. opcodes.insert(0x17, new_opcode("OR", 2, 1, 3));
  265. opcodes.insert(0x18, new_opcode("XOR", 2, 1, 3));
  266. opcodes.insert(0x19, new_opcode("NOT", 1, 1, 3));
  267. opcodes.insert(0x1a, new_opcode("BYTE", 2, 1, 3));
  268. // crypto
  269. opcodes.insert(0x20, new_opcode("SHA3", 2, 1, 30));
  270. // contract context
  271. opcodes.insert(0x30, new_opcode("ADDRESS", 0, 1, 2));
  272. opcodes.insert(0x31, new_opcode("BALANCE", 1, 1, 20));
  273. opcodes.insert(0x32, new_opcode("ORIGIN", 0, 1, 2));
  274. opcodes.insert(0x33, new_opcode("CALLER", 0, 1, 2));
  275. opcodes.insert(0x34, new_opcode("CALLVALUE", 0, 1, 2));
  276. opcodes.insert(0x35, new_opcode("CALLDATALOAD", 1, 1, 3));
  277. opcodes.insert(0x36, new_opcode("CALLDATASIZE", 0, 1, 2));
  278. opcodes.insert(0x37, new_opcode("CALLDATACOPY", 3, 0, 3));
  279. opcodes.insert(0x38, new_opcode("CODESIZE", 0, 1, 2));
  280. opcodes.insert(0x39, new_opcode("CODECOPY", 3, 0, 3));
  281. opcodes.insert(0x3a, new_opcode("GASPRICE", 0, 1, 2));
  282. opcodes.insert(0x3b, new_opcode("EXTCODESIZE", 1, 1, 20));
  283. opcodes.insert(0x3c, new_opcode("EXTCODECOPY", 4, 0, 20));
  284. // blockchain context
  285. opcodes.insert(0x40, new_opcode("BLOCKHASH", 1, 1, 20));
  286. opcodes.insert(0x41, new_opcode("COINBASE", 0, 1, 2));
  287. opcodes.insert(0x42, new_opcode("TIMESTAMP", 0, 1, 2));
  288. opcodes.insert(0x43, new_opcode("NUMBER", 0, 1, 2));
  289. opcodes.insert(0x44, new_opcode("DIFFICULTY", 0, 1, 2));
  290. opcodes.insert(0x45, new_opcode("GASLIMIT", 0, 1, 2));
  291. // storage and execution
  292. opcodes.insert(0x50, new_opcode("POP", 1, 0, 2));
  293. opcodes.insert(0x51, new_opcode("MLOAD", 1, 1, 3));
  294. opcodes.insert(0x52, new_opcode("MSTORE", 2, 0, 3));
  295. opcodes.insert(0x53, new_opcode("MSTORE8", 2, 0, 3));
  296. opcodes.insert(0x54, new_opcode("SLOAD", 1, 1, 50));
  297. opcodes.insert(0x55, new_opcode("SSTORE", 2, 0, 0));
  298. opcodes.insert(0x56, new_opcode("JUMP", 1, 0, 8));
  299. opcodes.insert(0x57, new_opcode("JUMPI", 2, 0, 10));
  300. opcodes.insert(0x58, new_opcode("PC", 0, 1, 2));
  301. opcodes.insert(0x59, new_opcode("MSIZE", 0, 1, 2));
  302. opcodes.insert(0x5a, new_opcode("GAS", 0, 1, 2));
  303. opcodes.insert(0x5b, new_opcode("JUMPDEST", 0, 0, 1));
  304. // logging
  305. opcodes.insert(0xa0, new_opcode("LOG0", 2, 0, 375));
  306. opcodes.insert(0xa1, new_opcode("LOG1", 3, 0, 750));
  307. opcodes.insert(0xa2, new_opcode("LOG2", 4, 0, 1125));
  308. opcodes.insert(0xa3, new_opcode("LOG3", 5, 0, 1500));
  309. opcodes.insert(0xa4, new_opcode("LOG4", 6, 0, 1875));
  310. // closures
  311. opcodes.insert(0xf0, new_opcode("CREATE", 3, 1, 32000));
  312. opcodes.insert(0xf1, new_opcode("CALL", 7, 1, 40));
  313. opcodes.insert(0xf2, new_opcode("CALLCODE", 7, 1, 40));
  314. opcodes.insert(0xf3, new_opcode("RETURN", 2, 0, 0));
  315. opcodes.insert(0xf4, new_opcode("DELEGATECALL", 6, 0, 40));
  316. opcodes.insert(0xff, new_opcode("SUICIDE", 1, 0, 0));
  317. for i in 1..33 {
  318. let name = format!("PUSH{}", i);
  319. opcodes.insert(0x5f + i, new_opcode(&name, 0, 1, 3));
  320. }
  321. for i in 1..17 {
  322. let name = format!("DUP{}", i);
  323. opcodes.insert(0x7f + i, new_opcode(&name, i as u32, i as u32 + 1, 3));
  324. let name = format!("SWAP{}", i);
  325. opcodes.insert(0x8f + i, new_opcode(&name, i as u32 + 1, i as u32 + 1, 3));
  326. }
  327. opcodes
  328. }
  329. #[cfg(test)]
  330. mod tests {
  331. use super::*;
  332. #[test]
  333. fn stack_simple_push_pop() {
  334. let mut s = Stack::new();
  335. s.push(str_to_u256("1"));
  336. s.push(str_to_u256("2"));
  337. s.push(str_to_u256("3"));
  338. assert_eq!(s.pop(), str_to_u256("3"));
  339. assert_eq!(s.pop(), str_to_u256("2"));
  340. assert_eq!(s.pop(), str_to_u256("1"));
  341. // assert_eq!(s.pop(), str_to_u256("1"));
  342. // assert_eq!(s.pop(), error); // TODO expect error as stack is empty
  343. }
  344. // arithmetic
  345. #[test]
  346. fn execute_opcodes_0() {
  347. let code = hex::decode("6005600c01").unwrap(); // 5+12
  348. let calldata = vec![];
  349. let mut s = Stack::new();
  350. s.execute(&code, &calldata, false);
  351. assert_eq!(s.pop(), str_to_u256("17"));
  352. assert_eq!(s.gas, 9999999991);
  353. assert_eq!(s.pc, 5);
  354. }
  355. #[test]
  356. fn execute_opcodes_1() {
  357. let code = hex::decode("60056004016000526001601ff3").unwrap();
  358. let calldata = vec![];
  359. let mut s = Stack::new();
  360. let out = s.execute(&code, &calldata, false);
  361. assert_eq!(out[0], 0x09);
  362. assert_eq!(s.gas, 9999999976);
  363. assert_eq!(s.pc, 12);
  364. // assert_eq!(s.pop(), err); // TODO expect error as stack is empty
  365. }
  366. #[test]
  367. fn execute_opcodes_2() {
  368. let code = hex::decode("61010161010201").unwrap();
  369. let calldata = vec![];
  370. let mut s = Stack::new();
  371. s.execute(&code, &calldata, false);
  372. // assert_eq!(out[0], 0x09);
  373. assert_eq!(s.gas, 9999999991);
  374. assert_eq!(s.pc, 7);
  375. assert_eq!(s.pop(), str_to_u256("515"));
  376. }
  377. }