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.

578 lines
20 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 print_stack(&self) {
  53. for i in (0..self.stack.len()).rev() {
  54. println!("{:x?}", &self.stack[i][28..]);
  55. }
  56. }
  57. 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 input into a 32
  61. // byte array
  62. 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. 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[32 - b.len()..].copy_from_slice(&b[..]);
  73. let l = self.stack.len();
  74. self.stack[l - 1] = d;
  75. }
  76. fn pop(&mut self) -> [u8; 32] {
  77. match self.stack.pop() {
  78. Some(x) => return x,
  79. None => panic!("err"),
  80. }
  81. }
  82. fn execute(&mut self, code: &[u8], calldata: &[u8], debug: bool) -> Vec<u8> {
  83. self.pc = 0;
  84. self.calldata_i = 0;
  85. let l = code.len();
  86. while self.pc < l {
  87. let opcode = code[self.pc];
  88. if !self.opcodes.contains_key(&opcode) {
  89. panic!("invalid opcode {:x}", opcode);
  90. }
  91. if debug {
  92. println!(
  93. "{:?} (0x{:x}): pc={:?} gas={:?}\nstack:",
  94. self.opcodes.get(&opcode).unwrap().name,
  95. opcode,
  96. self.pc,
  97. self.gas,
  98. );
  99. self.print_stack();
  100. println!("");
  101. }
  102. match opcode & 0xf0 {
  103. 0x00 => {
  104. // arithmetic
  105. match opcode {
  106. 0x00 => {
  107. return Vec::new();
  108. }
  109. 0x01 => self.add(),
  110. 0x02 => self.mul(),
  111. 0x03 => self.sub(),
  112. 0x04 => self.div(),
  113. 0x05 => self.sdiv(),
  114. 0x06 => self.modulus(),
  115. 0x07 => self.smod(),
  116. 0x08 => self.add_mod(),
  117. 0x09 => self.mul_mod(),
  118. 0x0a => self.exp(),
  119. // 0x0b => self.sign_extend(),
  120. _ => panic!("unimplemented {:x}", opcode),
  121. }
  122. self.pc += 1;
  123. }
  124. 0x30 => {
  125. match opcode {
  126. 0x35 => {
  127. self.calldata_load(&calldata);
  128. }
  129. _ => panic!("unimplemented {:x}", opcode),
  130. }
  131. self.pc += 1;
  132. }
  133. 0x50 => {
  134. self.pc += 1;
  135. match opcode {
  136. 0x51 => self.mload(),
  137. 0x52 => self.mstore(),
  138. 0x56 => self.jump(),
  139. 0x57 => {
  140. self.jump_i();
  141. }
  142. 0x5b => {
  143. self.jump_dest();
  144. }
  145. _ => panic!("unimplemented {:x}", opcode),
  146. }
  147. }
  148. 0x60 | 0x70 => {
  149. // push
  150. let n = (opcode - 0x5f) as usize;
  151. self.push_arbitrary(&code[self.pc + 1..self.pc + 1 + n]);
  152. self.pc += 1 + n;
  153. }
  154. 0x80 => {
  155. // 0x8x dup
  156. let l = self.stack.len();
  157. if opcode > 0x7f {
  158. self.stack.push(self.stack[l - (opcode - 0x7f) as usize]);
  159. } else {
  160. self.stack.push(self.stack[(0x7f - opcode) as usize]);
  161. }
  162. self.pc += 1;
  163. }
  164. 0x90 => {
  165. // 0x9x swap
  166. let l = self.stack.len();
  167. let pos;
  168. if opcode > 0x8e {
  169. pos = l - (opcode - 0x8e) as usize;
  170. } else {
  171. pos = (0x8e - opcode) as usize;
  172. }
  173. let tmp = self.stack[pos];
  174. self.stack[pos] = self.stack[l - 1];
  175. self.stack[l - 1] = tmp;
  176. self.pc += 1;
  177. }
  178. 0xf0 => {
  179. if opcode == 0xf3 {
  180. let pos_to_return = u256_to_u64(self.pop()) as usize;
  181. let len_to_return = u256_to_u64(self.pop()) as usize;
  182. return self.mem[pos_to_return..pos_to_return + len_to_return].to_vec();
  183. }
  184. }
  185. _ => {
  186. panic!("unimplemented {:x}", opcode);
  187. }
  188. }
  189. self.gas -= self.opcodes.get(&opcode).unwrap().gas;
  190. }
  191. return Vec::new();
  192. }
  193. // arithmetic
  194. // TODO instead of [u8;32] converted to BigUint, use custom type uint256 that implements all
  195. // the arithmetic
  196. fn add(&mut self) {
  197. let b0 = BigUint::from_bytes_be(&self.pop()[..]);
  198. let b1 = BigUint::from_bytes_be(&self.pop()[..]);
  199. self.push_arbitrary(&(b0 + b1).to_bytes_be());
  200. }
  201. fn mul(&mut self) {
  202. let b0 = BigUint::from_bytes_be(&self.pop()[..]);
  203. let b1 = BigUint::from_bytes_be(&self.pop()[..]);
  204. self.push_arbitrary(&(b0 * b1).to_bytes_be());
  205. }
  206. fn sub(&mut self) {
  207. let b0 = BigUint::from_bytes_be(&self.pop()[..]);
  208. let b1 = BigUint::from_bytes_be(&self.pop()[..]);
  209. if b0 >= b1 {
  210. self.push_arbitrary(&(b0 - b1).to_bytes_be());
  211. } else {
  212. // 2**256
  213. let max =
  214. "115792089237316195423570985008687907853269984665640564039457584007913129639936"
  215. .parse::<BigUint>()
  216. .unwrap();
  217. self.push_arbitrary(&(max + b0 - b1).to_bytes_be());
  218. }
  219. }
  220. fn div(&mut self) {
  221. let b0 = BigUint::from_bytes_be(&self.pop()[..]);
  222. let b1 = BigUint::from_bytes_be(&self.pop()[..]);
  223. self.push_arbitrary(&(b0 / b1).to_bytes_be());
  224. }
  225. fn sdiv(&mut self) {
  226. panic!("unimplemented");
  227. }
  228. fn modulus(&mut self) {
  229. let b0 = BigUint::from_bytes_be(&self.pop()[..]);
  230. let b1 = BigUint::from_bytes_be(&self.pop()[..]);
  231. self.push_arbitrary(&(b0 % b1).to_bytes_be());
  232. }
  233. fn smod(&mut self) {
  234. panic!("unimplemented");
  235. }
  236. fn add_mod(&mut self) {
  237. let b0 = BigUint::from_bytes_be(&self.pop()[..]);
  238. let b1 = BigUint::from_bytes_be(&self.pop()[..]);
  239. let b2 = BigUint::from_bytes_be(&self.pop()[..]);
  240. self.push_arbitrary(&(b0 + b1 % b2).to_bytes_be());
  241. }
  242. fn mul_mod(&mut self) {
  243. let b0 = BigUint::from_bytes_be(&self.pop()[..]);
  244. let b1 = BigUint::from_bytes_be(&self.pop()[..]);
  245. let b2 = BigUint::from_bytes_be(&self.pop()[..]);
  246. self.push_arbitrary(&(b0 * b1 % b2).to_bytes_be());
  247. }
  248. fn exp(&mut self) {
  249. panic!("unimplemented");
  250. // let b0 = BigUint::from_bytes_be(&self.pop()[..]);
  251. // let b1 = BigUint::from_bytes_be(&self.pop()[..]);
  252. // self.push_arbitrary(&(pow(b0, b1)).to_bytes_be());
  253. }
  254. // boolean
  255. // crypto
  256. // contract context
  257. fn calldata_load(&mut self, calldata: &[u8]) {
  258. self.put_arbitrary(&calldata[self.calldata_i..self.calldata_i + 32]);
  259. self.calldata_i += 32;
  260. }
  261. // blockchain context
  262. // storage and execution
  263. fn extend_mem(&mut self, start: usize, size: usize) {
  264. if size <= self.mem.len() || start + size <= self.mem.len() {
  265. return;
  266. }
  267. let old_size = self.mem.len() / 32;
  268. let new_size = (start + size) / 32;
  269. let old_total_fee = old_size * GMEMORY + old_size.pow(2) / GQUADRATICMEMDENOM;
  270. let new_total_fee = new_size * GMEMORY + new_size.pow(2) / GQUADRATICMEMDENOM;
  271. let mem_fee = new_total_fee - old_total_fee;
  272. self.gas -= mem_fee as u64;
  273. let mut new_bytes: Vec<u8> = vec![0; size];
  274. self.mem.append(&mut new_bytes);
  275. }
  276. fn mload(&mut self) {
  277. let pos = u256_to_u64(self.pop()) as usize;
  278. self.extend_mem(pos as usize, 32);
  279. let mem32 = self.mem[pos..pos + 32].to_vec();
  280. self.push_arbitrary(&mem32);
  281. }
  282. fn mstore(&mut self) {
  283. let pos = u256_to_u64(self.pop());
  284. let val = self.pop();
  285. self.extend_mem(pos as usize, 32);
  286. self.mem[pos as usize..].copy_from_slice(&val);
  287. }
  288. fn jump(&mut self) {
  289. // TODO that jump destination is valid
  290. self.pc = u256_to_u64(self.pop()) as usize;
  291. }
  292. fn jump_i(&mut self) {
  293. let new_pc = u256_to_u64(self.pop()) as usize;
  294. if self.stack.len() > 0 {
  295. let cond = u256_to_u64(self.pop()) as usize;
  296. if cond != 0 {
  297. self.pc = new_pc;
  298. }
  299. }
  300. // let cont = self.pop();
  301. // if cont {} // TODO depends on having impl Err in pop()
  302. }
  303. fn jump_dest(&mut self) {
  304. // TODO
  305. }
  306. }
  307. fn u256_to_u64(a: [u8; 32]) -> u64 {
  308. let mut b8: [u8; 8] = [0; 8];
  309. b8.copy_from_slice(&a[32 - 8..32]);
  310. let pos = u64::from_be_bytes(b8);
  311. pos
  312. }
  313. fn str_to_u256(s: &str) -> [u8; 32] {
  314. let bi = s.parse::<BigUint>().unwrap().to_bytes_be();
  315. let mut r: [u8; 32] = [0; 32];
  316. r[32 - bi.len()..].copy_from_slice(&bi[..]);
  317. r
  318. }
  319. struct Opcode {
  320. name: String,
  321. ins: u32,
  322. outs: u32,
  323. gas: u64,
  324. // operation: fn(),
  325. }
  326. fn new_opcode(name: &str, ins: u32, outs: u32, gas: u64) -> Opcode {
  327. Opcode {
  328. name: name.to_string(),
  329. ins,
  330. outs,
  331. gas,
  332. }
  333. }
  334. fn new_opcodes() -> HashMap<u8, Opcode> {
  335. let mut opcodes: HashMap<u8, Opcode> = HashMap::new();
  336. // arithmetic
  337. opcodes.insert(0x00, new_opcode("STOP", 0, 0, 0));
  338. opcodes.insert(0x01, new_opcode("ADD", 2, 1, 3));
  339. opcodes.insert(0x02, new_opcode("MUL", 2, 1, 5));
  340. opcodes.insert(0x03, new_opcode("SUB", 2, 1, 3));
  341. opcodes.insert(0x04, new_opcode("DIV", 2, 1, 5));
  342. opcodes.insert(0x05, new_opcode("SDIV", 2, 1, 5));
  343. opcodes.insert(0x06, new_opcode("MOD", 2, 1, 5));
  344. opcodes.insert(0x07, new_opcode("SMOD", 2, 1, 5));
  345. opcodes.insert(0x08, new_opcode("ADDMOD", 3, 1, 8));
  346. opcodes.insert(0x09, new_opcode("MULMOD", 3, 1, 8));
  347. opcodes.insert(0x0a, new_opcode("EXP", 2, 1, 10));
  348. opcodes.insert(0x0b, new_opcode("SIGNEXTEND", 2, 1, 5));
  349. // boolean
  350. opcodes.insert(0x10, new_opcode("LT", 2, 1, 3));
  351. opcodes.insert(0x11, new_opcode("GT", 2, 1, 3));
  352. opcodes.insert(0x12, new_opcode("SLT", 2, 1, 3));
  353. opcodes.insert(0x13, new_opcode("SGT", 2, 1, 3));
  354. opcodes.insert(0x14, new_opcode("EQ", 2, 1, 3));
  355. opcodes.insert(0x15, new_opcode("ISZERO", 1, 1, 3));
  356. opcodes.insert(0x16, new_opcode("AND", 2, 1, 3));
  357. opcodes.insert(0x17, new_opcode("OR", 2, 1, 3));
  358. opcodes.insert(0x18, new_opcode("XOR", 2, 1, 3));
  359. opcodes.insert(0x19, new_opcode("NOT", 1, 1, 3));
  360. opcodes.insert(0x1a, new_opcode("BYTE", 2, 1, 3));
  361. // crypto
  362. opcodes.insert(0x20, new_opcode("SHA3", 2, 1, 30));
  363. // contract context
  364. opcodes.insert(0x30, new_opcode("ADDRESS", 0, 1, 2));
  365. opcodes.insert(0x31, new_opcode("BALANCE", 1, 1, 20));
  366. opcodes.insert(0x32, new_opcode("ORIGIN", 0, 1, 2));
  367. opcodes.insert(0x33, new_opcode("CALLER", 0, 1, 2));
  368. opcodes.insert(0x34, new_opcode("CALLVALUE", 0, 1, 2));
  369. opcodes.insert(0x35, new_opcode("CALLDATALOAD", 1, 1, 3));
  370. opcodes.insert(0x36, new_opcode("CALLDATASIZE", 0, 1, 2));
  371. opcodes.insert(0x37, new_opcode("CALLDATACOPY", 3, 0, 3));
  372. opcodes.insert(0x38, new_opcode("CODESIZE", 0, 1, 2));
  373. opcodes.insert(0x39, new_opcode("CODECOPY", 3, 0, 3));
  374. opcodes.insert(0x3a, new_opcode("GASPRICE", 0, 1, 2));
  375. opcodes.insert(0x3b, new_opcode("EXTCODESIZE", 1, 1, 20));
  376. opcodes.insert(0x3c, new_opcode("EXTCODECOPY", 4, 0, 20));
  377. // blockchain context
  378. opcodes.insert(0x40, new_opcode("BLOCKHASH", 1, 1, 20));
  379. opcodes.insert(0x41, new_opcode("COINBASE", 0, 1, 2));
  380. opcodes.insert(0x42, new_opcode("TIMESTAMP", 0, 1, 2));
  381. opcodes.insert(0x43, new_opcode("NUMBER", 0, 1, 2));
  382. opcodes.insert(0x44, new_opcode("DIFFICULTY", 0, 1, 2));
  383. opcodes.insert(0x45, new_opcode("GASLIMIT", 0, 1, 2));
  384. // storage and execution
  385. opcodes.insert(0x50, new_opcode("POP", 1, 0, 2));
  386. opcodes.insert(0x51, new_opcode("MLOAD", 1, 1, 3));
  387. opcodes.insert(0x52, new_opcode("MSTORE", 2, 0, 3));
  388. opcodes.insert(0x53, new_opcode("MSTORE8", 2, 0, 3));
  389. opcodes.insert(0x54, new_opcode("SLOAD", 1, 1, 50));
  390. opcodes.insert(0x55, new_opcode("SSTORE", 2, 0, 0));
  391. opcodes.insert(0x56, new_opcode("JUMP", 1, 0, 8));
  392. opcodes.insert(0x57, new_opcode("JUMPI", 2, 0, 10));
  393. opcodes.insert(0x58, new_opcode("PC", 0, 1, 2));
  394. opcodes.insert(0x59, new_opcode("MSIZE", 0, 1, 2));
  395. opcodes.insert(0x5a, new_opcode("GAS", 0, 1, 2));
  396. opcodes.insert(0x5b, new_opcode("JUMPDEST", 0, 0, 1));
  397. // logging
  398. opcodes.insert(0xa0, new_opcode("LOG0", 2, 0, 375));
  399. opcodes.insert(0xa1, new_opcode("LOG1", 3, 0, 750));
  400. opcodes.insert(0xa2, new_opcode("LOG2", 4, 0, 1125));
  401. opcodes.insert(0xa3, new_opcode("LOG3", 5, 0, 1500));
  402. opcodes.insert(0xa4, new_opcode("LOG4", 6, 0, 1875));
  403. // closures
  404. opcodes.insert(0xf0, new_opcode("CREATE", 3, 1, 32000));
  405. opcodes.insert(0xf1, new_opcode("CALL", 7, 1, 40));
  406. opcodes.insert(0xf2, new_opcode("CALLCODE", 7, 1, 40));
  407. opcodes.insert(0xf3, new_opcode("RETURN", 2, 0, 0));
  408. opcodes.insert(0xf4, new_opcode("DELEGATECALL", 6, 0, 40));
  409. opcodes.insert(0xff, new_opcode("SUICIDE", 1, 0, 0));
  410. for i in 1..33 {
  411. let name = format!("PUSH{}", i);
  412. opcodes.insert(0x5f + i, new_opcode(&name, 0, 1, 3));
  413. }
  414. for i in 1..17 {
  415. let name = format!("DUP{}", i);
  416. opcodes.insert(0x7f + i, new_opcode(&name, i as u32, i as u32 + 1, 3));
  417. let name = format!("SWAP{}", i);
  418. opcodes.insert(0x8f + i, new_opcode(&name, i as u32 + 1, i as u32 + 1, 3));
  419. }
  420. opcodes
  421. }
  422. #[cfg(test)]
  423. mod tests {
  424. use super::*;
  425. #[test]
  426. fn stack_simple_push_pop() {
  427. let mut s = Stack::new();
  428. s.push(str_to_u256("1"));
  429. s.push(str_to_u256("2"));
  430. s.push(str_to_u256("3"));
  431. assert_eq!(s.pop(), str_to_u256("3"));
  432. assert_eq!(s.pop(), str_to_u256("2"));
  433. assert_eq!(s.pop(), str_to_u256("1"));
  434. // assert_eq!(s.pop(), str_to_u256("1"));
  435. // assert_eq!(s.pop(), error); // TODO expect error as stack is empty
  436. }
  437. // arithmetic
  438. #[test]
  439. fn execute_opcodes_0() {
  440. let code = hex::decode("6005600c01").unwrap(); // 5+12
  441. let calldata = vec![];
  442. let mut s = Stack::new();
  443. s.execute(&code, &calldata, false);
  444. assert_eq!(s.pop(), str_to_u256("17"));
  445. assert_eq!(s.gas, 9999999991);
  446. assert_eq!(s.pc, 5);
  447. }
  448. #[test]
  449. fn execute_opcodes_1() {
  450. let code = hex::decode("60056004016000526001601ff3").unwrap();
  451. let calldata = vec![];
  452. let mut s = Stack::new();
  453. let out = s.execute(&code, &calldata, false);
  454. assert_eq!(out[0], 0x09);
  455. assert_eq!(s.gas, 9999999976);
  456. assert_eq!(s.pc, 12);
  457. // assert_eq!(s.pop(), err); // TODO expect error as stack is empty
  458. }
  459. #[test]
  460. fn execute_opcodes_2() {
  461. let code = hex::decode("61010161010201").unwrap();
  462. let calldata = vec![];
  463. let mut s = Stack::new();
  464. s.execute(&code, &calldata, false);
  465. // assert_eq!(out[0], 0x09);
  466. assert_eq!(s.gas, 9999999991);
  467. assert_eq!(s.pc, 7);
  468. assert_eq!(s.pop(), str_to_u256("515"));
  469. }
  470. #[test]
  471. fn execute_opcodes_3() {
  472. // contains calldata
  473. let code = hex::decode("60003560203501").unwrap();
  474. let calldata = hex::decode("00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000004").unwrap();
  475. let mut s = Stack::new();
  476. s.execute(&code, &calldata, false);
  477. assert_eq!(s.gas, 9999999985);
  478. assert_eq!(s.pc, 7);
  479. assert_eq!(s.pop(), str_to_u256("9"));
  480. }
  481. // storage and execution
  482. #[test]
  483. fn execute_opcodes_4() {
  484. // contains loops
  485. let code = hex::decode("6000356000525b600160005103600052600051600657").unwrap();
  486. let calldata =
  487. hex::decode("0000000000000000000000000000000000000000000000000000000000000005")
  488. .unwrap();
  489. let mut s = Stack::new();
  490. s.execute(&code, &calldata, false);
  491. assert_eq!(s.gas, 9999999795);
  492. assert_eq!(s.pc, 22);
  493. assert_eq!(s.stack.len(), 0);
  494. }
  495. #[test]
  496. fn execute_opcodes_5() {
  497. // contains loops, without using mem
  498. let code = hex::decode("6000355b6001900380600357").unwrap();
  499. let calldata =
  500. hex::decode("0000000000000000000000000000000000000000000000000000000000000001")
  501. .unwrap();
  502. let mut s = Stack::new();
  503. s.execute(&code, &calldata, false);
  504. assert_eq!(s.gas, 9999999968);
  505. assert_eq!(s.pc, 12);
  506. let code = hex::decode("6000355b6001900380600357").unwrap();
  507. let calldata =
  508. hex::decode("0000000000000000000000000000000000000000000000000000000000000002")
  509. .unwrap();
  510. let mut s = Stack::new();
  511. s.execute(&code, &calldata, false);
  512. assert_eq!(s.gas, 9999999942);
  513. assert_eq!(s.pc, 12);
  514. let code = hex::decode("6000355b6001900380600357").unwrap();
  515. let calldata =
  516. hex::decode("0000000000000000000000000000000000000000000000000000000000000005")
  517. .unwrap();
  518. let mut s = Stack::new();
  519. s.execute(&code, &calldata, false);
  520. assert_eq!(s.gas, 9999999864);
  521. assert_eq!(s.pc, 12);
  522. }
  523. }